/**
 * Setvor project
 */
package setvor.npc;

import static java.lang.System.*;

import java.lang.reflect.InvocationTargetException;

/**
 * @author julatec
 *
 */
public final class NativeClassLoader extends ClassLoader {

	/**
	 * 
	 */
	public NativeClassLoader() {
		super();
	}

	/**
	 * @param parent
	 */
	public NativeClassLoader(ClassLoader parent) {
		super(parent);
	}
	
	private static NativeClassLoader instance = new NativeClassLoader(ClassLoader.getSystemClassLoader());
	
	public static NativeClassLoader getInstance(){
		return instance;
	}
	
	public void loadClass(Class<? extends NativeWriteable> clazz) 
			throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
		if(clazz.isAnnotationPresent(LibraryReference.class)){
			LibraryReference reference = clazz.getAnnotation(LibraryReference.class);
			if(reference.libraryPath() != null){
				String libraryPath = getenv("java.library.path");
				getenv().put("java.library.path",  libraryPath + ";" + reference.libraryPath());
			}
			if(reference.libraryName()  == null)
				throw new IllegalArgumentException("reference.libraryName() can not be null.");
			load(reference.libraryName());
			clazz.getDeclaredMethod("nativeLoadClass").invoke(null);
		}else
			throw new IllegalArgumentException(clazz.getName() + "has not LibraryReference annotation");
	}
}
